package com.hdax.dm.controller;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.hdax.dm.dto.OrderDto;
import com.hdax.dm.exceptions.DmException;
import com.hdax.dm.feign.ItemFeign;
import com.hdax.dm.feign.LinkUserFeign;
import com.hdax.dm.feign.SchedulerFeign;
import com.hdax.dm.item.Item;
import com.hdax.dm.order.DmOrder;
import com.hdax.dm.order.DmOrderLinkUser;
import com.hdax.dm.scheduler.DmSchedulerSeat;
import com.hdax.dm.scheduler.DmSchedulerSeatPrice;
import com.hdax.dm.service.OrderLinkUserService;
import com.hdax.dm.service.OrderService;
import com.hdax.dm.user.DmLinkUser;
import com.hdax.dm.utils.response.CommonResponse;
import com.hdax.dm.utils.response.ResponseUtils;
import com.hdax.dm.utils.token.Token;
import com.hdax.dm.vo.OrderVo;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@RestController
@RequestMapping(path = "/order")
public class OrderController {

    @Autowired
    private LinkUserFeign linkUserFeign;
    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderLinkUserService orderLinkUserService;
    @Autowired
    private ItemFeign itemFeign;
    @Autowired
    private SchedulerFeign schedulerFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //根据登录人的id查询常用购票人
    @PostMapping(path = "/p/ticketbuyerlist")
    public CommonResponse<List<DmLinkUser>> ticketbuyerlist(@RequestBody Map<String,String> map) throws IOException {

        String redisToken = redisTemplate.opsForValue().get("token");
        Long userid = 0L;
        if(redisToken!=null){
            Token token = new Token();
            Boolean tokenMsg = token.TokenId(redisToken);
            if(tokenMsg){
                userid = token.getUserId();
            }
        }


        List<DmLinkUser> userList = linkUserFeign.userList(userid);
        return ResponseUtils.returnSuccess(userList);
    }

    //获取登录人的id查询订单
    @PostMapping(path = "/queryorderlist")
    public CommonResponse<List<OrderDto>> queryorderlist() throws IOException {

        String redisToken = redisTemplate.opsForValue().get("token");
        Long userid = 0L;
        if(redisToken!=null){
            Token token = new Token();
            Boolean tokenMsg = token.TokenId(redisToken);
            if(tokenMsg){
                userid = token.getUserId();
            }
        }
        return orderService.orders(userid);
    }

    //删除联系人
    @PostMapping(path = "/deleteticketbuyer")
    public CommonResponse<String> deleteticketbuyer(@RequestBody Map<String,String> map){

        String id = map.get("linkId");
        String msg;
        Boolean bo = linkUserFeign.deleteLinkUser(Long.valueOf(id));
        if(bo){
            msg = "删除成功";
        }else {
            msg = "删除失败";
        }
        return ResponseUtils.returnSuccess(msg,msg);
    }
    //检查购票人是否存在
    @PostMapping(path = "/validatebuyerexist")
    public CommonResponse validatebuyerexist(@RequestBody Map<String,String> map){
        String idcard = map.get("idCard");
        String b = "";
        if(linkUserFeign.validatebuyerexist(idcard)){
            b="1009";
        }else {
            b="0000";
        }
        return ResponseUtils.returnFail(b,b);
    }
    //添加常用购票人
    @PostMapping(path = "/addticketbuyer")
    public CommonResponse<String> addticketbuyer(@RequestBody Map<String,String> map){
        String redisToken = redisTemplate.opsForValue().get("token");
        Long userid = 0L;
        if(redisToken!=null){
            Token token = new Token();
            Boolean tokenMsg = token.TokenId(redisToken);
            if(tokenMsg){
                userid = token.getUserId();
            }
        }
        DmLinkUser user = new DmLinkUser();
        user.setUserId(userid);
        user.setCardType(Long.valueOf(map.get("cardType")));
        user.setIdCard(map.get("idCard"));
        user.setName(map.get("name"));
        user.setCreatedTime(LocalDateTime.from(LocalDate.now()));
        user.setUpdatedTime(LocalDateTime.from(LocalDate.now()));
        String name = "";
        if(linkUserFeign.addticketbuyer(user)){
            name ="添加成功";
        }else {
            name = "添加失败";
        }
        return ResponseUtils.returnSuccess(name);
    }





    //提交订单
    @PostMapping(path = "/submitorder")
    public CommonResponse<String> submitorder(@RequestBody OrderVo vo){

        while(redisTemplate.opsForValue().setIfAbsent("lock","lock",500, TimeUnit.MILLISECONDS)){

        }

        DmOrder order = new DmOrder();
        //从token中获取用户id
            String tokenStr = redisTemplate.opsForValue().get("token");
            Token token = new Token();
            Long userId = 0L;
            if(tokenStr!=null){
                if(token.TokenId(tokenStr)){
                    userId = token.getUserId();
                }
            } else {
                System.out.println("鉴权失败");
                throw new DmException("8888","鉴权失败");
            }
        //雪花算法生成订单id
            Snowflake snowflake = IdUtil.getSnowflake(1, 1);
            String id = snowflake.nextIdStr();
        order.setOrderNo(id);
        order.setUserId(userId);
        order.setSchedulerId(vo.getSchedulerId());
        order.setItemId(vo.getItemId());
        Long itemid = order.getItemId();
        //根据itemid查询数据
        List<Item> items = itemFeign.items(itemid);
        items.forEach(item->{
            order.setItemName(item.getItemName());
        });
        order.setOrderType(0L);
        //是否需要发票
        order.setIsNeedInvoice(vo.getIsNeedInvoice());
        if(order.getIsNeedInvoice()==1){
            order.setSourceType(vo.getSourceType());
            order.setInvoiceHead(vo.getInvoiceHead());
            order.setInvoiceNo(vo.getInvoiceNo());
        }
        //因为要从中拿到seat表id所以声明在这

        //总价格
        AtomicReference<Double> toPrice = new AtomicReference<>(0.0);
        //3. 解析座位 x1_y1,x2_y2
        String[] seats = vo.getSeatPositions().split(",");
        //定义int类型的数组，长度为解析后的length
        Double[] prices = new Double[seats.length];
        order.setTotalCount(Long.valueOf(seats.length));
        //解析开始
        for (var ref = new Object() {int i = 0;}; ref.i < seats.length; ref.i++) {
            Long x = Long.parseLong(seats[ref.i].split("_")[0]);
            Long y = Long.parseLong(seats[ref.i].split("_")[1]);

            //对实体类添加数据为修改做准备
            DmSchedulerSeat seat = new DmSchedulerSeat();
            //根据x,y和排期id查询 拿到areaLevle
            List<DmSchedulerSeat> seatsList = schedulerFeign.dmSchedulerSeat(x,y,order.getSchedulerId());
            seatsList.forEach(seatsLists->{
                seat.setId(seatsLists.getId());
                //拿到areaLevle 和排期id 对价格进行查询，
                List<DmSchedulerSeatPrice> priceList = schedulerFeign.schedulerPriceIdAreaId(order.getSchedulerId(),seatsLists.getAreaLevel());
                priceList.forEach(p->{
                    //把拿到的价格汇总
                    toPrice.updateAndGet(v -> v + p.getPrice());
                    prices[ref.i] = p.getPrice();
                });
            });
            seat.setScheduleId(order.getSchedulerId());
            seat.setOrderNo(order.getOrderNo());
            seat.setUserId(order.getUserId());
            seat.setStatus(2L);
            seat.setUpdatedTime(LocalDateTime.now());
            //修改座位状态
            try {
                schedulerFeign.updataSeat(seat);
            }catch (Exception e){
                //如果异常加入队列
                System.out.println("座位状态异常");
                rabbitTemplate.convertAndSend("dm_seat_dlx_exchange","dm.seat",order.getOrderNo());
            }
        }

        //4. 解析订单联系人  id1,id2
        String[] linkIds = vo.getLinkIds().split(",");
        for (int i = 0; i < linkIds.length; i++) {
            DmOrderLinkUser orderUser = new DmOrderLinkUser();

            //获取xy座位信息


            Long  x= Long.parseLong(seats[i].split("_")[0]);
            Long  y= Long.parseLong(seats[i].split("_")[1]);
            orderUser.setOrderId(order.getOrderNo());
            orderUser.setLinkUserId(Long.valueOf(linkIds[i]));
            //根据联系人id查询联系人姓名
            List<DmLinkUser> linkUsers = linkUserFeign.userListId(orderUser.getLinkUserId());
            linkUsers.forEach(user -> {
                orderUser.setLinkUserName(user.getName());
            });
            orderUser.setX(x);
            orderUser.setY(y);
            orderUser.setPrice(prices[i]);
            orderUser.setCreatedTime(LocalDateTime.now());
            //添加订单联系人
            try {
                orderLinkUserService.save(orderUser);
            }catch (Exception e){
            //如果异常加入队列
            System.out.println("添加订单联系人异常");
                rabbitTemplate.convertAndSend("dm_seat_dlx_exchange","dm.seat",order.getOrderNo());
                rabbitTemplate.convertAndSend("dm_linkUser_dlx_exchange","dm.linkUser",order.getOrderNo());
            }
        }






        //是否需要保险（是：+20）
        order.setIsNeedInsurance(vo.getIsNeedInsurance());
        if(order.getIsNeedInsurance()==1){
            order.setInsuranceAmount(20.0*linkIds.length);
           toPrice.updateAndGet(v -> v + order.getInsuranceAmount());
        }
        //拿到总价
        order.setTotalAmount(toPrice.get());
        order.setCreatedTime(LocalDateTime.now());

        //添加订单
        try {
            orderService.save(order);
            rabbitTemplate.convertAndSend("dm_order_exchange","dm.order",order.getOrderNo(),
                message -> {
                    //设置持久化
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    //过期时间
                    message.getMessageProperties().setExpiration(60000*15+"");
                    return message;
                });
        }catch (Exception e){
            //如果异常加入队列
            System.out.println("添加订单异常");
            rabbitTemplate.convertAndSend("dm_seat_dlx_exchange","dm.seat",order.getOrderNo());
            rabbitTemplate.convertAndSend("dm_linkUser_dlx_exchange","dm.linkUser",order.getOrderNo());
            rabbitTemplate.convertAndSend("dm_orderDel_dlx_exchange","dm.dlx.order",order.getOrderNo());
        }

        redisTemplate.delete("lock");
        System.out.println("输出order");
        return ResponseUtils.returnSuccess(order.getOrderNo());
    }
}
